package top.sdwu_top.kbase.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import top.sdwu_top.kbase.common.aspect.exception.MyException;
import top.sdwu_top.kbase.dto.KbaseKnowledgeTagDto;
import top.sdwu_top.kbase.entity.KbaseAuthUser;
import top.sdwu_top.kbase.entity.KbaseKnowledgeTag;
import top.sdwu_top.kbase.mapper.KbaseKnowledgeTagMapper;
import top.sdwu_top.kbase.service.IKbaseFileTagService;
import top.sdwu_top.kbase.service.IKbaseKnowledgeTagService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import top.sdwu_top.kbase.vo.KbaseKnowledgeTagVo;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 知识标签 服务实现类
 * </p>
 *
 * @author zhipeng.duan@nvr-china.com
 * @since 2020-02-20
 */
@Service
public class KbaseKnowledgeTagServiceImpl extends ServiceImpl<KbaseKnowledgeTagMapper, KbaseKnowledgeTag> implements IKbaseKnowledgeTagService {

    @Autowired
    IKbaseFileTagService fileTagService;

    @Override
    public Page<KbaseKnowledgeTag> page(KbaseKnowledgeTagVo knowledgeTagVo) {
        QueryWrapper<KbaseKnowledgeTag> qw = Wrappers.query();
        if (StringUtils.isNotBlank(knowledgeTagVo.getKeyword())) {
            qw.or(i->{
                i.like("TAG_NAME", knowledgeTagVo.getKeyword())
                        .or()
                        .like("TAG_CONTENT", knowledgeTagVo.getKeyword());
            });
        }
        qw.eq(StringUtils.isNotBlank(knowledgeTagVo.getTagName()), "TAG_NAME", knowledgeTagVo.getTagName())
                .eq(StringUtils.isNotBlank(knowledgeTagVo.getParentId()), "PARENT_ID", knowledgeTagVo.getParentId());
        return super.page(knowledgeTagVo.getPage(), qw);
    }

    @Override
    public boolean save(KbaseKnowledgeTag knowlageTag) {
        if (StringUtils.isBlank(knowlageTag.getTagName())) {
            throw new MyException(50003, "标签名不能为空");
        }
        if (exist(knowlageTag)) {
            throw new MyException(50003, "标签名已存在");
        }
        return super.save(knowlageTag);
    }

    @Override
    public boolean update(KbaseAuthUser user, KbaseKnowledgeTag knowlageTag) {
        KbaseKnowledgeTag tag = super.getById(knowlageTag.getId());
        if (Objects.isNull(tag)) {
            return true;
        }
        if (!Objects.equals(user.getId(), tag.getCreatedBy())) {
            throw new MyException(403, "无权操作该标签");
        }
        if (StringUtils.isBlank(knowlageTag.getId())) {
            return false;
        }
        if (exist(knowlageTag)) {
            throw new MyException(50003, "已存在该标签");
        }
        return super.saveOrUpdate(knowlageTag);
    }

    public boolean delete(KbaseAuthUser user, String id) {
        KbaseKnowledgeTag tag = super.getById(id);
        if (Objects.isNull(tag)) {
            return true;
        }
        if (!Objects.equals(user.getId(), tag.getCreatedBy())) {
            throw new MyException(403, "无权操作该标签");
        }
        if (hasChild(tag.getId())) {
            throw new MyException(50003, "该标签含有子标签，无法删除");
        }
        return super.removeById(id);
    }

    @Override
    public KbaseKnowledgeTagDto getChain(String id) {
        KbaseKnowledgeTag knowlageTag = super.getById(id);
        if (Objects.isNull(knowlageTag)) {
            return new KbaseKnowledgeTagDto();
        }
        List<KbaseKnowledgeTag> nowList = Lists.newArrayList(knowlageTag);
        while(CollectionUtils.isNotEmpty(nowList)) {
            List<KbaseKnowledgeTag> tempList = Lists.newArrayList();
            for (KbaseKnowledgeTag kbaseKnowlageTag : nowList) {
                List<KbaseKnowledgeTag> childList = getChildList(kbaseKnowlageTag.getId());
                kbaseKnowlageTag.setChildList(childList);
                tempList.addAll(childList);
            }
            nowList.clear();
            nowList.addAll(tempList);
            tempList.clear();
        }
        KbaseKnowledgeTagDto result = new KbaseKnowledgeTagDto();
        BeanUtils.copyProperties(knowlageTag, result);
        KbaseKnowledgeTag parentTag = super.getById(result.getParentId());
        if (Objects.nonNull(parentTag)) {
            result.setParentTagName(parentTag.getTagName());
        }
        return result;
    }

    @Override
    public List<KbaseKnowledgeTag> getTagTreeList(KbaseAuthUser user) {
        QueryWrapper<KbaseKnowledgeTag> qw = Wrappers.query();
        qw.isNull("PARENT_ID");
        List<KbaseKnowledgeTag> tagList = super.list(qw);
        if (CollectionUtils.isEmpty(tagList)) {
            return Lists.newArrayListWithExpectedSize(0);
        }
        tagList.parallelStream().forEach(tag->{
            tag.setChildList(getChain(tag.getId()).getChildList());
        });
        return tagList;
    }

    @Override
    public List<KbaseKnowledgeTag> getListByFileId(String fileId) {
        List<String> tagIdList = fileTagService.getTagIdListByFileId(fileId);
        if (CollectionUtils.isEmpty(tagIdList)) {
            return Lists.newArrayListWithExpectedSize(0);
        }
        QueryWrapper<KbaseKnowledgeTag> qw = Wrappers.query();
        qw.in("ID", tagIdList);
        return super.list(qw);
    }

    @Override
    public List<String> getIdListByKeyword(String keyword) {
        if (StringUtils.isBlank(keyword)) {
            return Lists.newArrayListWithExpectedSize(0);
        }
        QueryWrapper<KbaseKnowledgeTag> qw = Wrappers.query();
        qw.like("TAG_NAME", keyword);
        List<KbaseKnowledgeTag> tagList = super.list(qw);
        if (CollectionUtils.isEmpty(tagList)) {
            return Lists.newArrayListWithExpectedSize(0);
        }
        return tagList.parallelStream().map(KbaseKnowledgeTag::getId).collect(Collectors.toList());
    }

    @Override
    public List<String> getNameListByIdList(List<String> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return Lists.newArrayListWithExpectedSize(0);
        }
        LambdaQueryWrapper<KbaseKnowledgeTag> qw = Wrappers.lambdaQuery();
        qw.in(KbaseKnowledgeTag::getId, idList);
        List<KbaseKnowledgeTag> tagList = super.list(qw);
        if (CollectionUtils.isEmpty(tagList)) {
            return Lists.newArrayListWithExpectedSize(0);
        }
        return tagList.parallelStream().map(KbaseKnowledgeTag::getTagName).collect(Collectors.toList());
    }


    private boolean exist(KbaseKnowledgeTag knowlageTag) {
        QueryWrapper<KbaseKnowledgeTag> qw = Wrappers.query();
        qw.eq("TAG_NAME", knowlageTag.getTagName());
        KbaseKnowledgeTag result = super.getOne(qw);
        return Objects.nonNull(result);
    }

    private List<KbaseKnowledgeTag> getChildList(String id) {
        if (StringUtils.isBlank(id)) {
            return Lists.newArrayListWithExpectedSize(0);
        }
        QueryWrapper<KbaseKnowledgeTag> qw = Wrappers.query();
        qw.eq("PARENT_ID", id);
        List<KbaseKnowledgeTag> knowlageTagList = super.list(qw);
        if (CollectionUtils.isEmpty(knowlageTagList)) {
            return Lists.newArrayListWithExpectedSize(0);
        }
        return knowlageTagList;
    }

    private boolean hasChild(String parentId) {
        if (StringUtils.isBlank(parentId)) {
            return false;
        }
        QueryWrapper<KbaseKnowledgeTag> qw = Wrappers.query();
        qw.eq("PARENT_ID", parentId);
        qw.last("limit 1");
        return Objects.nonNull(super.getOne(qw));
    }

}
